home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / tde40.zip / pull.c < prev    next >
C/C++ Source or Header  |  1994-06-05  |  9KB  |  299 lines

  1. /*
  2.  * These functions do the pop-up pull-down command menus.
  3.  *
  4.  * Being stupid, I can't remember what half the function keys do.
  5.  *  Fortunately, it is very easy to write a pop-up pull-down command menu
  6.  *  to run editor commands.  Being lazy, I didn't implement CUA style menus,
  7.  *  because we can provide most of the CUA benefits with a single hot-key.
  8.  *  Also, dumb UNIX terminals don't have a lot function keys to spare.
  9.  *
  10.  * New editor name:  TDE, the Thomson-Davis Editor.
  11.  * Author:           Frank Davis
  12.  * Date:             June 5, 1991, version 1.0
  13.  * Date:             July 29, 1991, version 1.1
  14.  * Date:             October 5, 1991, version 1.2
  15.  * Date:             January 20, 1992, version 1.3
  16.  * Date:             February 17, 1992, version 1.4
  17.  * Date:             April 1, 1992, version 1.5
  18.  * Date:             June 5, 1992, version 2.0
  19.  * Date:             October 31, 1992, version 2.1
  20.  * Date:             April 1, 1993, version 2.2
  21.  * Date:             June 5, 1993, version 3.0
  22.  * Date:             August 29, 1993, version 3.1
  23.  * Date:             November 13, 1993, version 3.2
  24.  * Date:             June 5, 1994, version 4.0
  25.  *
  26.  * This code is released into the public domain, Frank Davis.
  27.  *    You may distribute it freely.
  28.  */
  29.  
  30. #include "tdestr.h"
  31. #include "common.h"
  32. #include "define.h"
  33. #include "tdefunc.h"
  34.  
  35.  
  36. static int saved_major = 0;
  37. static int saved_minor = 0;
  38.  
  39.  
  40. /*
  41.  * Name:    main_pull_down
  42.  * Purpose: show pull down menu and call function if needed
  43.  * Date:    November 13, 1993
  44.  * Passed:  window:  current window
  45.  * Notes:   keep a record of the last menu choice in local global variables.
  46.  */
  47. int  main_pull_down( TDE_WIN *window )
  48. {
  49. int rc;
  50. int ch;
  51. int row;
  52. int major_choice;
  53. int minor_choice;
  54. #if defined( __UNIX__ )
  55.  chtype display_buff[MAX_COLS+2];       /* chtype is defined in curses.h */
  56. #else
  57.  char display_buff[(MAX_COLS+2)*2];
  58. #endif
  59.  
  60.    rc = ERROR;
  61.    row = 0;
  62.    major_choice = saved_major;
  63.    minor_choice = saved_minor;
  64.    save_screen_line( 0, row, display_buff );
  65.    ch = lite_bar_menu( &major_choice, &minor_choice );
  66.    restore_screen_line( 0, row, display_buff );
  67.    saved_major = major_choice;
  68.    saved_minor = minor_choice;
  69.    if (ch == Rturn) {
  70.       g_status.command = menu[major_choice].minor[minor_choice].minor_func;
  71.       g_status.control_break = FALSE;
  72.       if (g_status.command >= 0 && g_status.command < NUM_FUNCS)
  73.          rc = (*do_it[g_status.command])( window );
  74.       else
  75.          rc = ERROR;
  76.    }
  77.    return( rc );
  78. }
  79.  
  80.  
  81. /*
  82.  * Name:    lite_bar_menu
  83.  * Purpose: handle major menu choices
  84.  * Date:    November 13, 1993
  85.  * Passed:  maj: pointer to menu bar choice
  86.  *          min: pointer to function under menu
  87.  * Returns: last key pressed
  88.  * Notes:   set the menu structures
  89.  */
  90. int lite_bar_menu( int *maj, int *min )
  91. {
  92. int  major_col[MAJOR];
  93. int  major_width[MAJOR];
  94. int  col;
  95. int  row;
  96. int  wid;
  97. int  ch;
  98. char blanks[MAX_COLS+2];
  99.  
  100.    /*
  101.     * put the pull-down menu on the first line of screen.
  102.     */
  103.    col = row = 0;
  104.    memset( blanks, ' ', g_display.ncols );
  105.    blanks[g_display.ncols] = '\0';
  106.    s_output( blanks, row, col, g_display.head_color );
  107.    get_bar_spacing( col+1, major_col, major_width );
  108.    draw_lite_head( row, major_col );
  109.  
  110.    xygoto( -1, -1 );
  111.    get_minor_counts( );
  112.    ch = -1;
  113.    while (ch != AbortCommand  &&  ch != Rturn) {
  114.       if (ch == CharRight) {
  115.          hlight_line( major_col[*maj], row, major_width[*maj], g_display.mode_color );
  116.          ++*maj;
  117.          if (*maj >= MAJOR)
  118.             *maj = 0;
  119.          *min = 0;
  120.          ch = -1;
  121.       } else if (ch == CharLeft) {
  122.          hlight_line( major_col[*maj], row, major_width[*maj], g_display.mode_color );
  123.          --*maj;
  124.          if (*maj < 0)
  125.             *maj = MAJOR - 1;
  126.          *min = 0;
  127.          ch = -1;
  128.       }
  129.  
  130.       hlight_line( major_col[*maj], row, major_width[*maj], g_display.block_color );
  131.  
  132. #if defined( __UNIX__ )
  133.       refresh( );
  134. #endif
  135.  
  136.       col = major_col[*maj];
  137.       wid = strlen( menu[*maj].minor[0].minor_name );
  138.       if (col + wid + 2 > g_display.ncols - 1)
  139.          col = g_display.ncols - 1 - wid;
  140.       *min = pull_me( *maj, *min, row+1, col, &ch );
  141.    }
  142.    return( ch );
  143. }
  144.  
  145.  
  146. /*
  147.  * Name:    pull_me
  148.  * Purpose: move cursor up and down the menu bar
  149.  * Date:    November 13, 1993
  150.  * Passed:  maj: main menu bar choice
  151.  *          min: subfunction choice
  152.  *          row: row to begin vertical choice
  153.  *          col: column to begin vertical choice
  154.  *          ch:  pointer to current key
  155.  * Returns: last key pressed
  156.  * Notes:   save the text under the pulled down menu
  157.  */
  158. int  pull_me( int maj, int min, int row, int col, int *ch )
  159. {
  160. int  i;
  161. int  minor_width;
  162. int  cnt;
  163. int  select;
  164. int  begin;
  165. int  end;
  166. #if defined( __UNIX__ )
  167.  chtype *buffer;
  168. #else
  169.  int  *buffer;
  170. #endif
  171.  
  172.    cnt = menu[maj].minor_cnt;
  173.  
  174.    /*
  175.     * find first valid minor selection.
  176.     */
  177.    for (begin=0; menu[maj].minor[begin].minor_func < 0; begin++);
  178.  
  179.    /*
  180.     * find last valid minor selection
  181.     */
  182.    for (end=cnt-1; menu[maj].minor[end].minor_func < 0; end--);
  183.  
  184.    minor_width = strlen( menu[maj].minor[0].minor_name );
  185.  
  186.    select = min;
  187.    if (menu[maj].minor[select].minor_func < 0) {
  188.       select = begin;
  189.       while (menu[maj].minor[select].minor_func < 0)
  190.          ++select;
  191.    }
  192.  
  193. #if defined( __UNIX__ )
  194.    buffer = (chtype *)malloc( minor_width * cnt * sizeof(chtype) );
  195. #else
  196.    buffer = (int *)malloc( minor_width * cnt * sizeof(int) );
  197. #endif
  198.    if (buffer != NULL) {
  199.       save_minor_area( buffer, minor_width, cnt, row, col );
  200.       for (i=0; i< cnt; i++)
  201.          s_output( menu[maj].minor[i].minor_name, row+i, col, g_display.help_color );
  202.  
  203.       hlight_line( col+1, row+select, minor_width-2, g_display.hilited_file );
  204.       while (*ch != AbortCommand && *ch != CharRight &&
  205.                            *ch != CharLeft && *ch != Rturn) {
  206.          if (*ch == LineDown) {
  207.             hlight_line( col+1, row+select, minor_width-2, g_display.help_color );
  208.             ++select;
  209.             while (menu[maj].minor[select].minor_func < 0)
  210.                ++select;
  211.             if (select >= cnt)
  212.                select = begin;
  213.             hlight_line( col+1, row+select, minor_width-2, g_display.hilited_file );
  214.          } else if (*ch == LineUp) {
  215.             hlight_line( col+1, row+select, minor_width-2, g_display.help_color );
  216.             --select;
  217.             while (menu[maj].minor[select].minor_func < 0)
  218.                --select;
  219.             if (select < 0)
  220.                select = end;
  221.             hlight_line( col+1, row+select, minor_width-2, g_display.hilited_file );
  222.          }
  223.  
  224. #if defined( __UNIX__ )
  225.          refresh( );
  226. #endif
  227.  
  228.          *ch = getkey( );
  229.          *ch = getfunc( *ch );
  230.          if (*ch == ESC)
  231.             *ch = AbortCommand;
  232.       }
  233.       restore_minor_area( buffer, minor_width, cnt, row, col );
  234.       free( buffer );
  235.    } else {
  236.       select = -1;
  237.       *ch = AbortCommand;
  238.    }
  239.    return( select );
  240. }
  241.  
  242.  
  243. /*
  244.  * Name:    get_bar_spacing
  245.  * Purpose: calculate headings for main menu choices
  246.  * Date:    November 13, 1993
  247.  * Passed:  col: col of first menu choice
  248.  *          major_col: column to display each menu heading
  249.  *          major_width: width of each menu heading
  250.  * Notes:   assume 6 spaces between the menu items
  251.  */
  252. void get_bar_spacing( int col, int major_col[], int major_width[] )
  253. {
  254. int i, j;
  255.  
  256.    for (i=j=0; i< MAJOR; i++) {
  257.       major_col[i] = col+j;
  258.       major_width[i] = strlen( menu[i].major_name );
  259.       j += major_width[i] + 6;
  260.    }
  261. }
  262.  
  263.  
  264. /*
  265.  * Name:    draw_lite_head
  266.  * Purpose: slap the main menu choices on the lite bar
  267.  * Date:    November 13, 1993
  268.  * Passed:  row: lite bar row
  269.  *          major_col: column to display each menu heading
  270.  */
  271. void draw_lite_head( int row, int major_col[] )
  272. {
  273. int i;
  274.  
  275.    for (i=0; i< MAJOR; i++)
  276.       s_output( menu[i].major_name, row, major_col[i], g_display.mode_color );
  277.  
  278. #if defined( __UNIX__ )
  279.    refresh( );
  280. #endif
  281. }
  282.  
  283.